package com.gamebase.scence
{
	import com.gamebase.findPath.DirectPath;
	import com.gamebase.role.Role;
	import com.gamebase.role.ScenceObject;
	import com.gamebase.role.NPC;
	import com.gamebase.role.SubRole;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.net.URLRequest;
	import flash.utils.Timer;

	public class SubScence extends Sprite
	{
		public var referX:Number;//场景添加到舞台时的坐标，将作为舞台移动在起始参考点
		public var referY:Number;
		//寻路对象
		private var m_RoleMove:DirectPath;
		//场景加载器
		public var scenceLoader:SenceLoader;
		//场景swf对象
		private var m_SceneObject:MovieClip;
		//场景swf对象的前景部分
		private var bFront:BitmapData
		//场景swf对象的背景部分
		private var bBk:BitmapData
		//场景障碍层
		private var m_SceneHitTest:MovieClip;
		private var m_HitBitData:BitmapData;
		//角色层
		private var role_frame:Sprite;
		/*效果层*/
		public var scenceFront:Bitmap;
		private var m_EffectBitData:BitmapData;
		//主角色
		public var masterRole:SubRole;
		//场景移动时钟
		private var scenceMoveTimer:Timer;
		private var _fitStage:Boolean;
		/*在线用户列表*/
		public var roleList:Array;
		/*npc 列表*/
		public var ncpRoleList:Array; /*NPCRole*/
		////地图上其它的对象
		public var otherObjectArr:Array;
		
		public var iniCallBack:Function;//场景加载完成并已初始化后执行的回调函数
		
		/**
		 * @parma url：场景资源地址
		 * @parma showWidth:显示宽度
		 * @parma showHeight:显示高度
		 * */
		public function SubScence(url:String=null,fitStage:Boolean=false)
		{
			super();
			_fitStage = fitStage;
			roleList = new Array();
			ncpRoleList = new Array();
			otherObjectArr = new Array();
			this.addEventListener(Event.REMOVED_FROM_STAGE,destroy);
			this.addEventListener(Event.ADDED_TO_STAGE,addedToStage);
			if(url != null)
			{
				scenceLoader = new SenceLoader(this);
				scenceLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,onScenceLoad);
				scenceLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,loadError);
				scenceLoader.load(new URLRequest(url));
			}
		}
		
		private function addedToStage(evt:Event):void
		{
			this.removeEventListener(Event.ADDED_TO_STAGE,addedToStage);
			referX = this.x;
			referY = this.y;
		}
		
		private function loadError(evt:IOErrorEvent):void
		{
			trace(evt.text);
		}
		
		/**设置场景资源。适合场景资源在外部被加载后直接在这里设置
		 * */
		public function iniScence(m:MovieClip,fitStage:Boolean=false):void
		{
			_fitStage = fitStage;
			onScenceLoad(null,m);
		}
		
		private function onScenceLoad(evt:Event=null,scenceMovieClip:MovieClip=null):void
		{
			//地图SWF
			if(scenceMovieClip != null)
				m_SceneObject = scenceMovieClip;
			else if(evt.target)
			{
				m_SceneObject=evt.target.content as MovieClip;
				scenceLoader.setScenceSize(_fitStage);
			}
				
			
			//障碍层
			m_SceneHitTest=m_SceneObject._hitTest as MovieClip;
			//m_SceneHitTest.alpha = 0.5;
			m_HitBitData = new BitmapData( m_SceneHitTest.width,m_SceneHitTest.height,false,0x000000 ); 
			m_HitBitData.draw(m_SceneHitTest,null,null,null,new Rectangle(0,0,m_SceneHitTest.width,m_SceneHitTest.height) );
			//生成效果层放到role_frame中
			bFront=new BitmapData(m_SceneObject.front.width, m_SceneObject.front.height, true, 0x00);
			bBk=new BitmapData(m_SceneObject.bk.width, m_SceneObject.bk.height);
			bFront.draw(m_SceneObject.front);
			bBk.draw(m_SceneObject.bk);
			this.m_EffectBitData=new BitmapData(m_SceneObject.bk.width, m_SceneObject.bk.height);
			m_EffectBitData.copyPixels(bBk, new Rectangle(0, 0, m_SceneObject.bk.width, m_SceneObject.bk.height), new Point(0, 0), bFront, new Point(0, 0));
			this.scenceFront=new Bitmap(m_EffectBitData);
			//scenceFront.alpha=0.5;
			scenceFront.name="effectBitMapLayer";
			
			this.addChild(m_SceneObject);
			m_SceneObject.x = 0;
			m_SceneObject.y = 0;
			role_frame = new Sprite();
			this.addChild(role_frame);
			role_frame.addChild(scenceFront);
			
			m_RoleMove = new DirectPath(m_HitBitData);
			if(iniCallBack != null)
			{
				iniCallBack.call();
			}
			this.role_frame.addEventListener(MouseEvent.MOUSE_DOWN,onScenceClick);
			role_frame.scrollRect = new Rectangle(0,0,m_SceneObject.width,m_SceneObject.height);
			
			
		}
		
		public function addRole(role:SubRole,isMasterRole:Boolean=false):void
		{
			role_frame.addChild(role);
			roleList.push(role);
			checkToOther(role);
			role.addEventListener(Event.REMOVED_FROM_STAGE,removeRoleObject);
			if(isMasterRole)
			{
				this.masterRole = role;
				this.scenceLoader.m_Role = role;
				//检查场景是否应该移动
				if(scenceMoveTimer == null)
				{
					scenceMoveTimer = new Timer(50);
					scenceMoveTimer.addEventListener(TimerEvent.TIMER,checkScenceMove);
				}
				scenceMoveTimer.start();
			}
		}
		
		public function addNPC(npc:NPC):void
		{
			role_frame.addChild(npc);
			ncpRoleList.push(npc);
			checkToOther(npc);
			npc.addEventListener(Event.REMOVED_FROM_STAGE,removeRoleObject);
		}
		
		/**添加场景物件
		 * @param object
		 * @param changStation 是否需要将注册点转移到物件下方中点
		 * 请设置好object的坐标后再调用此方法，或者将返回值赋给object的输入参数变量
		 * */
		public function addObject(object:DisplayObject,changStation:Boolean=true):ScenceObject
		{
			var scenceObject:ScenceObject = object as ScenceObject;
			if(scenceObject == null)
			{
				if(changStation)
				{
					scenceObject = new ScenceObject();
					scenceObject.setObject(object);
				}
				else
				{
					scenceObject = new ScenceObject(object);
				}
					
			}
			otherObjectArr.push(scenceObject);
			role_frame.addChild(scenceObject);
			checkToOther(scenceObject);
			scenceObject.addEventListener(Event.REMOVED_FROM_STAGE,removeRoleObject);
			return scenceObject;
		}
		
		private function removeRoleObject(evt:Event):void
		{
			if(evt.target is SubRole)
				removeRole(evt.target as SubRole);
			else if(evt.target is NPC)
				removeNPC(evt.target as NPC);
			else if(evt.target is NPC)
				removeScenceObject(evt.target as ScenceObject);
			
		}
		
		public function removeRole(role:SubRole):void
		{
			var i:uint = 0;
			while(i < ncpRoleList.length)
			{
				if(ncpRoleList[i] == role)
				{
					ncpRoleList.splice(i,1);
					break;
				}
				i++;
			}
			role_frame.removeChild(role);
			role.destroy();
		}
		
		public function removeNPC(npc:NPC):void
		{
			var i:uint = 0;
			while(i < ncpRoleList.length)
			{
				if(ncpRoleList[i] == npc)
				{
					ncpRoleList.splice(i,1);
					break;
				}
				i++;
			}
			role_frame.removeChild(npc);
			npc.destroy();
		}
		
		public function removeScenceObject(obj:ScenceObject):void
		{
			var i:uint = 0;
			while(i < otherObjectArr.length)
			{
				if(otherObjectArr[i] == obj)
				{
					otherObjectArr.splice(i,1);
					break;
				}
				i++;
			}
			role_frame.removeChild(obj);
			//obj.destroy();
		}
		
		private function checkScenceMove(evt:TimerEvent):void
		{
			var stagPoint:Point = new Point(-referX+masterRole.x+this.x,-referY+masterRole.y+this.y);
			if( (stagPoint.x<250) || (stagPoint.x > (scenceLoader.showScenceWidth-250)) || 
			(stagPoint.y > (scenceLoader.showScenceHeight - 250)) || (stagPoint.y < 250) )
			{
				scenceLoader.checkSenceMove(masterRole.roleMode.m_MoveAngle,stagPoint);
			}
		}
				
		//调整当前角色与其它角色、场景物件相互之间的层次关系
		public function checkToOther(currentRole:DisplayObject):void
		{
			var i:uint = 0;
			var compareRole:DisplayObject;
			var allRoleList:Array = roleList.concat(ncpRoleList).concat(otherObjectArr)//.concat(["effectBitMapLayer"]);
			var roleNum:uint = allRoleList.length;
			while(i < roleNum-1)
			{
				compareRole = allRoleList[i] as DisplayObject;
				if(compareRole == currentRole)
				{
					i++;
					continue;
				}
				if(currentRole.y < compareRole.y)
				{
					if(role_frame.getChildIndex(currentRole) > role_frame.getChildIndex(compareRole) )
					{
						role_frame.setChildIndex(currentRole,role_frame.getChildIndex(compareRole));
					}
				}
				else if(currentRole.y > compareRole.y)
				{
					if(role_frame.getChildIndex(currentRole) < role_frame.getChildIndex(compareRole) )
					{
						role_frame.setChildIndex(currentRole,role_frame.getChildIndex(compareRole));
					}
				}
				i++;
			}
			
			//检测是否与场景物件相碰
			if(m_EffectBitData == null)
				return;
			i = 0;
			(currentRole as Role).clearFront();
			while(i<10)
			{
				if(bFront.getPixel32(currentRole.x+3*i,currentRole.y+3*i) != 0)
				{
					(currentRole as Role).drawFront(m_EffectBitData/*,scenceFront.localToGlobal(new Point(0,0))*/);
					break;
				}
				if(bFront.getPixel32(currentRole.x-3*i,currentRole.y+3*i) != 0)
				{
					(currentRole as Role).drawFront(m_EffectBitData/*,scenceFront.localToGlobal(new Point(0,0))*/);
					break;
				}
				i++;
			}	
		}
		
		/**
		 * @param startP,endP 都是相对role_frame的坐标点(可看成SubScence的坐标点)
		 * */
		public function findPath(startP:Point,endP:Point):Array
		{
			return m_RoleMove.findPassPath(startP,endP);
		}
		
		//点击场景，检查是否点中人物、NPC或是背景等
		private function onScenceClick(evt:MouseEvent):void
		{
			var objArr:Array = this.stage.getObjectsUnderPoint(new Point(evt.stageX,evt.stageY));
			var i:int = objArr.length-1;
			var clickScence:Boolean = true;
			var role:*;
			var e:SubScenceEvent;
			while(i > -1)
			{
				if(objArr[i] is Bitmap)
				{
					if(objArr[i].parent.parent is SubRole)//点中人
					{
						role = objArr[i].parent.parent;
						if(!role.containPoint(role.mouseX,role.mouseY))
						{
							i--;
							continue;
						}
			            //抛出点中人事件：
			            e = new SubScenceEvent(SubScenceEvent.roleClick,role);
			            this.dispatchEvent(e);
			        	clickScence = false;
						break;
					}
					else if(objArr[i].parent.parent is NPC)//点中NPC
					{
						role = objArr[i].parent.parent;
						if(!role.containPoint(role.mouseX,role.mouseY))
						{
							i--;
							continue;
						}
						//抛出点中NPC事件：
			            e = new SubScenceEvent(SubScenceEvent.npcClick,role);
			            this.dispatchEvent(e);
						clickScence = false;
						break;
					}
					else if(objArr[i].parent is ScenceObject)
					{
						//抛出点中场景物件事件：
			            e = new SubScenceEvent(SubScenceEvent.scenceObjectClick,objArr[i].parent);
			            this.dispatchEvent(e);
						clickScence = false;
						break;
					}
				}
				i--;
			}
			if(clickScence)
			{
				e = new SubScenceEvent(SubScenceEvent.scenceClick);
			    this.dispatchEvent(e);
			}
		}
		
		public function destroy(e:Event=null):void
		{
			if(scenceMoveTimer != null)
			{
				scenceMoveTimer.stop();
				scenceMoveTimer.removeEventListener(TimerEvent.TIMER,checkScenceMove);
				scenceMoveTimer=null;
			}
			this.removeEventListener(Event.REMOVED_FROM_STAGE,destroy);
			if(scenceLoader != null)
			{
				this.role_frame.removeEventListener(MouseEvent.MOUSE_DOWN,onScenceClick);
				scenceLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE,onScenceLoad);
				scenceLoader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR,loadError);
				scenceLoader.unload();
				scenceLoader = null;
			}
		}
	}
}